import { NgModule, OnDestroy } from '@angular/core';
import { Route, Router, RouterModule, Routes } from '@angular/router';
import { RouterGuard } from './guards/router.guard';
import { ManageLayoutComponent } from './components/manage-layout/manage-layout.component';
import { UserComponent } from './pages/system-setting/user/page/user.component';
import { RoleComponent } from './pages/system-setting/role/page/role.component';
import { MenuComponent } from './pages/system-setting/menu/page/menu.component';
import { AuthService } from './services/auth.service';
import { DictComponent } from './pages/system-setting/dict/page/dict.component';
import { LoginComponent } from './pages/auth/login/login.component';
import { DeptComponent } from './pages/system-setting/dept/page/dept.component';
import { PostComponent } from './pages/system-setting/post/page/post.component';
import { ConfigComponent } from './pages/system-setting/config/page/config.component';
import { NoticeComponent } from './pages/system-setting/notice/page/notice.component';
import { OperlogComponent } from './pages/system-setting/operlog/page/operlog.component';
import { LogininforComponent } from './pages/system-setting/logininfor/page/logininfor.component';
import { OnlineComponent } from './pages/system-setting/online/page/online.component';
import { JobComponent } from './pages/system-setting/job/page/job.component';
import { UserCenterComponent } from './pages/system-setting/user-center/page/user-center.component';
import { WebStorageService } from './services/webStorage.service';
import { LoadingComponent } from './pages/auth/loading/loading.component';
import { HomeComponent } from './pages/auth/home/home.component';
import { NoPageComponent } from './pages/auth/noPage/noPage.component';
import { map } from 'rxjs/operators';
import { AssignRoleComponent } from './pages/system-setting/assign-role/page/assign-role.component';
import { JobLogComponent } from './pages/system-setting/job-log/page/job-log.component';
import { AssignUserComponent } from './pages/system-setting/assign-user/page/assign-user.component';
import { ServerComponent } from './pages/system-setting/server/page/server.component';
import { CacheComponent } from './pages/system-setting/cache/page/cache.component';
import { CacheListComponent } from './pages/system-setting/cacheList/page/cacheList.component';
import { DruidComponent } from './pages/system-setting/druid/druid.component';
import { SwaggerComponent } from './pages/system-setting/swagger/swagger.component';
import {SystemMenuService} from "./pages/system-setting/menu/service/system-menu.service";
import {ClientComponent} from "./pages/system-setting/client/page/client.component";
import {TenantComponent} from "./pages/system-setting/tenant/page/tenant.component";
import {TenantPackageModule} from "./pages/system-setting/tenant-package/page/tenant-package.module";
import {TenantPackageComponent} from "./pages/system-setting/tenant-package/page/tenant-package.component";

export const loginPage: Route = {
    path: 'login',
    component: LoginComponent,
    data: { title: '后台登录' }
}
export const homePage: Route = {
    path: 'home',
    component: HomeComponent,
    canActivate: [RouterGuard],
    data: { title: '主页' }
}

export const noPage: Route = {
    path: '403',
    component: NoPageComponent,
}

export const userCenterPage: Route =     {
    path: 'userCenter',
    component: UserCenterComponent,
    data: { title: '个人中心' }
}

export const assignRolePage: Route =     {
    path: 'system/user-auth/role',
    children: [
        {
            path: '**',
            component: AssignRoleComponent,
            data: { title: '分配角色' }
        },
    ],
    data: { title: '分配角色' }
}

export const assignUserPage: Route =     {
    path: 'system/role-auth/user',
    children: [
        {
            path: '**',
            component: AssignUserComponent,
            data: { title: '分配用户' }
        },
    ],
    data: { title: '分配用户' }
}

export const jobLogPage: Route =     {
    path: 'monitor/job-log/index',
    children: [
        {
            path: '**',
            component: JobLogComponent,
            data: { title: '任务日志' }
        },
    ],
    data: { title: '任务日志' }
}



export const routes: Routes = [
    {
        path: '',
        pathMatch: 'full',
        redirectTo: 'login',
    },
    loginPage,
    noPage,
    {
        path: '**',
        component: LoadingComponent,
        canActivate: [RouterGuard],
    },
];



export const manageRoutes: Routes = [
    {
        path: '',
        redirectTo: homePage.path,
        pathMatch: 'full'
    },
    userCenterPage,
    assignRolePage,
    assignUserPage,
    jobLogPage
]

@NgModule({
    imports:[ RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule implements OnDestroy{
    componentMap: Map<string, any> = new Map<string, any>();
    allRoutes: Route[] = [];
    menus: Array<any> = [];
    menusMap: Map<string, string> = new Map<string, string>();//用于辅助目录，通过component得到目录的路径
    pathMap = new Map([
            ['/manage/'+userCenterPage.path, { title:userCenterPage.data.title}],
            ['/manage/'+homePage.path, { title:homePage.data.title}],
            ['/manage/'+assignRolePage.path+'/**', { title:assignRolePage.data.title}],
            ['/manage/'+assignUserPage.path+'/**', { title:assignUserPage.data.title}],
            ['/manage/'+jobLogPage.path+'/**', { title:jobLogPage.data.title}],
        ]
    );
    intervalId: any;
    constructor(private router: Router,
                private authService :AuthService,
                private systemMenu: SystemMenuService,
                private webStorageService : WebStorageService) {
        this.componentMap.set('system/user/index', UserComponent);
        this.componentMap.set('system/role/index', RoleComponent);
        this.componentMap.set('system/menu/index', MenuComponent);
        this.componentMap.set('system/dept/index', DeptComponent);
        this.componentMap.set('system/post/index', PostComponent);
        this.componentMap.set('system/dict/index', DictComponent);
        this.componentMap.set('system/config/index', ConfigComponent);
        this.componentMap.set('system/notice/index', NoticeComponent);
        this.componentMap.set('monitor/operlog/index', OperlogComponent);
        this.componentMap.set('monitor/logininfor/index', LogininforComponent);
        this.componentMap.set('monitor/online/index', OnlineComponent);
        this.componentMap.set('monitor/job/index', JobComponent);
        this.componentMap.set('monitor/server/index', ServerComponent);
        this.componentMap.set('monitor/cache/index', CacheComponent);
        this.componentMap.set('monitor/cache/list', CacheListComponent);
        this.componentMap.set('monitor/druid/index', DruidComponent);
        this.componentMap.set('tool/swagger/index', SwaggerComponent);
        this.componentMap.set('system/client/index', ClientComponent);
        this.componentMap.set('system/tenant/index', TenantComponent);
        this.componentMap.set('system/tenantPackage/index', TenantPackageComponent);
        if (!this.router.url.includes('/login')){
            this.initUserMenus();
        }
    }
    addRoutes(router: Route[]) {
        this.allRoutes = [...router,...routes]
        this.router.resetConfig(this.allRoutes)
        console.log('加载化路由完成', this.allRoutes);
    }

    /**
     * 根据用户获取菜单
     */
    getUserMenus() {
        return this.systemMenu.getUserMenu().pipe( map((res: any) => {
            if (res.code == 200){
                if (res.data.length == 0){
                    this.webStorageService.clear();
                    this.router.navigateByUrl('/login').then();
                }else {
                    console.log('获取菜单', res.data)
                    const routers: Route[] = this.recurRoute(res.data,true)
                    this.addRoutes(routers);
                    this.menus = res.data;
                }
            }
            return res;
        }))
    }

    /**
     * 根据用户获取菜单
     */
    initUserMenus() {
        console.log("准备初始化路由")
        if (this.webStorageService.getToken() !== null &&this.menus.length == 0 && this.menusMap.size == 0 ){
            this.getUserMenus().subscribe((res)=>{
                if (res.success){
                    this.startLoop()
                }
            });
        }else {
            console.log("条件不满足，停止初始化路由")
        }
    }


    startLoop() {
        this.intervalId = setInterval(() => {
            console.log('app-routing waiting menu load')
            if (this.menus.length != 0) {
                console.log("菜单加载完成",this.menus)
                console.log("组件加载完成",this.componentMap)
                this.initMenuMap('/manage' , this.menus);
                console.log("menusMap加载完成",this.menusMap)
                this.stopLoop();
            }else {
                console.log("菜单加载中")
            }
        }, 1000);
    }

    stopLoop() {
        if (this.intervalId) {
            clearInterval(this.intervalId);
            this.intervalId = null;
            console.log('app-routing end menu load')
        }
    }

    /**
     * 初始化菜单Map，使用页面组件名称，可以直接获得路由地址
     */
    initMenuMap(fatherUrl: string, childes: Array<any>){
        if (childes){
            childes.forEach(item => {
                let path = fatherUrl == '/manage' ? fatherUrl+item.path : fatherUrl +"/"+ item.path
                this.menusMap.set(item.component,path );
                this.pathMap.set(path,{title: item.meta.title });
                if (item.children){
                    this.initMenuMap(this.menusMap.get(item.component), item.children);
                }
            });
        }
    }


    recurRoute(items:any[],isFirst :boolean){
        let routes = [];
        if (!items) return [];
        items.forEach(item => {
            let router: Route ={
                path: item.path.replace('/', ''),
                component: this.componentMap.get(item.component),
                data: { title: item.meta.title||'' },
                children: this.recurRoute(item.children,false)
            }
            routes.push(router);
        })
        if (isFirst){
            routes.push(
                homePage,
                ...manageRoutes
            );
            return [{
                path: 'manage',
                component: ManageLayoutComponent,
                CanActivate: [RouterGuard],
                children: routes
            }];
        }else {
            return routes;
        }
    }

    ngOnDestroy(): void {
        this.stopLoop();
    }
}
